<!--
 * @Author: yanjikun
 * @Date: 2022-01-04 11:49:13
 * @LastEditors: yanjikun
 * @LastEditTime: 2022-05-16 15:23:30
 * @Description: file content
-->
<template>
  <Form v-bind="getFormProps" ref="basicFormRef" :model="formModel">
    <Row v-bind="getRowConfig">
      <template v-for="config in formConfigRef" :key="config.field">
        <FormItem
          :config="config"
          :form-model="formModel"
          :form-props="props"
          :set-form-model="setFormModel"
        >
          <template v-for="item in Object.keys($slots)" #[item]="data" :key="item">
            <slot :name="item" v-bind="data || {}"></slot>
          </template>
        </FormItem>
      </template>
      <FormAction v-bind="getFormActionBindProps">
        <template
          v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']"
          #[item]="slotData"
        >
          <slot :name="item" v-bind="slotData ?? {}"></slot>
        </template>
      </FormAction>
    </Row>
  </Form>
</template>

<script setup lang="ts">
  import { Form, Row } from 'ant-design-vue'
  import { basicProps } from './props'
  import FormItem from './components/FormItem.vue'
  import type { FormEmitType } from './types/form'
  import { useFormEvents } from './hooks/useFormEvents'
  import { useFormValues } from './hooks/useFormValues'
  import FormAction from './components/FormAction.vue'
  import { useFormState } from './hooks/useFormState'
  import { useFormMethods } from './hooks/useFormMethods'
  import { createFormContext } from './hooks/useFormContext'
  import { onMounted, useAttrs } from 'vue'
  defineOptions({
    name: 'BasicForm',
  })
  const attrs = useAttrs()
  interface emitType extends FormEmitType {}
  const emit = defineEmits<emitType>()
  const props = defineProps(basicProps)
  const formState = useFormState({ props, attrs })
  const {
    formModel,
    getFormProps,
    formConfigRef,
    getFormActionBindProps,
    getRowConfig,
    defaultFormValues,
    basicFormRef,
  } = formState
  const { initDefault, handleFormValues } = useFormValues({
    formConfigRef,
    formModel,
    getFormProps,
    defaultFormValues,
  })
  const formEvents = useFormEvents({
    emit,
    handleFormValues,
    ...formState,
  })
  const {
    validateFields,
    validate,
    resetFields,
    clearValidate,
    handleSubmit,
    setFieldsValue,
    updateConfig,
  } = formEvents
  const formMethods = useFormMethods(formState)
  const { setFormModel } = formMethods
  const instance = {
    ...formState,
    ...formEvents,
    ...formMethods,
  }
  createFormContext(instance)
  onMounted(() => {
    initDefault()
    emit('register', {
      validateFields,
      validate,
      resetFields,
      clearValidate,
      handleSubmit,
      setFieldsValue,
      updateConfig,
    })
  })

  defineExpose(instance)
</script>

<style scoped lang="less">
  .ant-form {
    padding: 0 4px;
  }
</style>
